package cn.iocoder.yudao.framework.pay.core.client.impl.epayments;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
import cn.iocoder.yudao.framework.pay.core.client.impl.epayments.model.BaseEPayResult;
import cn.iocoder.yudao.framework.pay.core.client.impl.epayments.model.EPayCreateAppOrderParam;
import cn.iocoder.yudao.framework.pay.core.client.impl.epayments.model.EPayCreateAppOrderResult;
import cn.iocoder.yudao.framework.pay.core.client.impl.epayments.model.EPayCreateSmartPayParam;
import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
import org.jetbrains.annotations.NotNull;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 聚合支付-通用支付
 * @author cai
 * @date 2024/02/28 15:26
 */
public abstract class EPaymentsSmartClient extends AbstractEPaymentsClient {

    public EPaymentsSmartClient(Long channelId, String channelCode, EPaymentsClientConfig config) {
        super(channelId, channelCode, config);
    }

    @Override
    protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws Throwable {
        // 1.1 构建 EPayCreateSmartPayParam 请求
        EPayCreateSmartPayParam param = buildEPayCreateSmartPayParam(reqDTO);
        // ② 个性化的参数
        Map<String, String> channelExtras = reqDTO.getChannelExtras();
        if (MapUtil.isNotEmpty(channelExtras)) {
        }
        // ③ 支付宝小程序支付可以使用APP模式
        String displayMode = PayOrderDisplayModeEnum.APP.getMode();

        // 2.1 执行请求
        BaseEPayResult result = client.genUrlResult(param, BaseEPayResult.class);
        // 2.2 处理结果
        if (!result.checkSuccess()) {
            return buildClosedPayOrderRespDTO(reqDTO, result);
        }
        // 大额支付，需要用户输入密码，所以返回 waiting。此时，前端一般会进行轮询
        return PayOrderRespDTO.waitingOf(displayMode, result.getContent(),
            reqDTO.getOutTradeNo(), result);
    }

    private @NotNull EPayCreateSmartPayParam buildEPayCreateSmartPayParam(PayOrderUnifiedReqDTO reqDTO) {
        // 1.1 构建 EPayCreateSmartPayParam 请求
        EPayCreateSmartPayParam param = new EPayCreateSmartPayParam();
        // ① 通用的参数
        param.setMerchant_id(this.config.getMerchantId());
        String orderId = reqDTO.getOutTradeNo();
        param.setIncrement_id(orderId);
        param.setGrandtotal(formatAmountDecimal(reqDTO.getPrice()));
        param.setCurrency(reqDTO.getCurrency());
        //param.setCurrency("CNY");
        Duration duration = Duration.between(LocalDateTime.now(), reqDTO.getExpireTime());
        Long minutes = duration.toMinutes() + 1;
        param.setValid_mins(minutes.intValue());
        param.setPayment_channels(getPaymentChannel());
        param.setReturn_url(reqDTO.getReturnUrl());
        param.setNotify_url(reqDTO.getNotifyUrl());
        param.setSubject(reqDTO.getSubject());
        param.setDescribe(reqDTO.getBody());
        param.setNonce_str(IdUtil.getSnowflakeNextIdStr());
        return param;
    }

    protected Map<String, String> getRequestHeaders() {
        Map<String, String> headers = new HashMap<>();
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 " + getPaymentChannel().toLowerCase());
        return headers;
    }

}
